/**
 * @file table_struct_attributes_demo.cpp
 * @brief 演示 FlatBuffers 中 Table vs Struct 和 Attributes 的用法
 */

#include <iostream>
#include <memory>
#include <vector>
#include <flatbuffers/flatbuffers.h>

// 包含生成的头文件
#include "table_vs_struct_demo_generated.h"

void demonstrateStructUsage() {
    std::cout << "\n=== Struct 使用示例 ===" << std::endl;
    
    // Struct 的创建和使用
    demo::Point3D point{10.5f, 20.3f, 5.8f};
    demo::RGBA color{255, 128, 64, 255};
    
    std::cout << "Point3D: (" << point.x() << ", " << point.y() << ", " << point.z() << ")" << std::endl;
    std::cout << "RGBA: (" << static_cast<int>(color.r()) << ", " 
              << static_cast<int>(color.g()) << ", " 
              << static_cast<int>(color.b()) << ", " 
              << static_cast<int>(color.a()) << ")" << std::endl;
    
    // Struct 特点：
    // 1. 固定大小：sizeof(Point3D) = 12 bytes
    // 2. 内存布局紧凑，没有额外开销
    // 3. 不支持可选字段或默认值
    std::cout << "Point3D 大小: " << sizeof(demo::Point3D) << " bytes" << std::endl;
    std::cout << "RGBA 大小: " << sizeof(demo::RGBA) << " bytes" << std::endl;
}

void demonstrateTableUsage() {
    std::cout << "\n=== Table 使用示例 ===" << std::endl;
    
    flatbuffers::FlatBufferBuilder builder(1024);
    
    // 创建字符串
    auto name = builder.CreateString("张三");
    auto email = builder.CreateString("zhangsan@example.com");
    
    // 创建 struct 对象
    demo::Point3D position{100.0f, 200.0f, 50.0f};
    demo::RGBA color{255, 0, 0, 255};
    
    // 创建背包物品列表
    std::vector<uint32_t> inventory_items = {1001, 1002, 1003, 2001};
    auto inventory = builder.CreateVector(inventory_items);
    
    // 创建 PlayerStats
    auto stats = demo::CreatePlayerStats(builder, 15, 12, 18);
    
    // 创建 Player table
    auto player = demo::CreatePlayer(builder,
        12345,          // id
        name,           // name (required)
        email,          // email
        &position,      // position (struct)
        &color,         // color (struct)
        25,             // level (默认值1)
        150,            // health (默认值100)
        80,             // mana (默认值50)
        0,              // old_score (deprecated)
        inventory,      // inventory
        stats           // stats
    );
    
    builder.Finish(player);
    
    // 读取数据
    auto root = demo::GetPlayer(builder.GetBufferPointer());
    
    std::cout << "玩家信息:" << std::endl;
    std::cout << "  ID: " << root->id() << std::endl;
    std::cout << "  姓名: " << root->name()->c_str() << std::endl;
    std::cout << "  邮箱: " << (root->email() ? root->email()->c_str() : "无") << std::endl;
    std::cout << "  等级: " << root->level() << std::endl;
    std::cout << "  生命值: " << root->health() << std::endl;
    std::cout << "  魔法值: " << root->mana() << std::endl;
    
    // 访问嵌入的 struct
    if (root->position()) {
        auto pos = root->position();
        std::cout << "  位置: (" << pos->x() << ", " << pos->y() << ", " << pos->z() << ")" << std::endl;
    }
    
    // 访问数组
    if (root->inventory()) {
        std::cout << "  背包物品: ";
        for (auto item_id : *root->inventory()) {
            std::cout << item_id << " ";
        }
        std::cout << std::endl;
    }
    
    // 访问嵌套 table
    if (root->stats()) {
        auto player_stats = root->stats();
        std::cout << "  属性: 力量=" << player_stats->strength() 
                  << ", 敏捷=" << player_stats->agility() 
                  << ", 智力=" << player_stats->intelligence() << std::endl;
    }
    
    std::cout << "序列化大小: " << builder.GetSize() << " bytes" << std::endl;
}

void demonstrateAttributes() {
    std::cout << "\n=== Attributes 使用说明 ===" << std::endl;
    
    std::cout << "1. key 属性: 标记主键字段，用于唯一标识" << std::endl;
    std::cout << "2. required 属性: 必需字段，反序列化时必须存在" << std::endl;
    std::cout << "3. deprecated 属性: 已弃用字段，向后兼容但不推荐使用" << std::endl;
    std::cout << "4. id 属性: 手动指定字段ID，用于版本兼容性" << std::endl;
    std::cout << "5. force_align 属性: 强制内存对齐" << std::endl;
    std::cout << "6. nested_flatbuffer 属性: 嵌套其他 FlatBuffer" << std::endl;
    
    // 演示带 ID 的表
    flatbuffers::FlatBufferBuilder builder(512);
    auto name = builder.CreateString("测试用户");
    
    auto player_with_ids = demo::CreatePlayerWithIds(builder,
        999,            // id (id: 0, key)
        name,           // name (id: 1, required)
        50,             // level (id: 2)
        125000          // experience (id: 3)
    );
    
    builder.Finish(player_with_ids);
    
    auto root = demo::GetPlayerWithIds(builder.GetBufferPointer());
    std::cout << "\n带ID属性的玩家:" << std::endl;
    std::cout << "  ID: " << root->id() << std::endl;
    std::cout << "  姓名: " << root->name()->c_str() << std::endl;
    std::cout << "  等级: " << root->level() << std::endl;
    std::cout << "  经验: " << root->experience() << std::endl;
}

void demonstrateVersionCompatibility() {
    std::cout << "\n=== 版本兼容性演示 ===" << std::endl;
    
    std::cout << "Table 的优势:" << std::endl;
    std::cout << "1. 可以添加新字段而不破坏旧代码" << std::endl;
    std::cout << "2. 可以设置默认值" << std::endl;
    std::cout << "3. 字段是可选的（除非标记为 required）" << std::endl;
    std::cout << "4. 支持 deprecated 字段标记" << std::endl;
    
    std::cout << "\nStruct 的特点:" << std::endl;
    std::cout << "1. 固定大小，性能更好" << std::endl;
    std::cout << "2. 内存布局紧凑" << std::endl;
    std::cout << "3. 不支持版本兼容性" << std::endl;
    std::cout << "4. 适合表示不变的数据结构（如坐标、颜色）" << std::endl;
}

int main() {
    std::cout << "FlatBuffers Table vs Struct 和 Attributes 演示" << std::endl;
    
    try {
        demonstrateStructUsage();
        demonstrateTableUsage();
        demonstrateAttributes();
        demonstrateVersionCompatibility();
        
        std::cout << "\n演示完成！" << std::endl;
        
    } catch (const std::exception& e) {
        std::cerr << "演示过程中发生异常: " << e.what() << std::endl;
        return -1;
    }
    
    return 0;
}
